/**
 * @p.md
 * 
 * DeadLetter 模块，处理无法投递的消息
 */
import { PID } from './pid';
import { Process } from './process';
import { Events } from './eventStream';
import { ActorSystem } from './actorSystem';

/**
 * 死信消息接口，表示无法投递的消息
 */
export interface DeadLetter {
  /**
   * 目标 PID
   */
  pid: PID;
  
  /**
   * 无法投递的消息
   */
  message: any;
  
  /**
   * 消息的发送者
   */
  sender?: PID;
}

/**
 * 创建死信消息对象
 * @param pid 目标 PID
 * @param message 无法投递的消息
 * @param sender 消息发送者
 * @returns 死信消息对象
 */
export function createDeadLetter(pid: PID, message: any, sender?: PID): DeadLetter {
  return { pid, message, sender };
}

/**
 * 死信进程，处理无法投递的消息
 */
export class DeadLetterProcess implements Process {
  /**
   * 构造函数
   * @param system Actor 系统
   */
  constructor(private readonly system: ActorSystem) {}

  /**
   * 处理用户消息
   * @param pid 目标 PID
   * @param message 用户消息
   */
  sendUserMessage(pid: PID, message: any): void {
    this.handleDeadLetter(pid, message);
  }

  /**
   * 处理系统消息
   * @param pid 目标 PID
   * @param message 系统消息
   */
  sendSystemMessage(pid: PID, message: any): void {
    this.handleDeadLetter(pid, message);
  }

  /**
   * 停止进程（无操作）
   * @param pid 要停止的 PID
   */
  stop(pid: PID): void {
    // 死信处理器不需要停止操作
  }

  /**
   * 处理死信
   * @param pid 目标 PID
   * @param message 消息
   */
  private handleDeadLetter(pid: PID, message: any): void {
    // 提取消息和发送者
    let actualMessage = message;
    let sender: PID | undefined;

    // 检查消息是否是信封格式
    if (message && typeof message === 'object' && 'message' in message && 'sender' in message) {
      actualMessage = message.message;
      sender = message.sender;
    }

    // 创建死信事件
    const deadLetter = new Events.DeadLetter(pid, actualMessage, sender);
    
    // 发布到事件流
    this.system.eventStream.publish(deadLetter);
    
    // 打印日志，方便调试
    console.warn(`[DeadLetter] Message sent to non-existent PID: ${pid.toString()}`, {
      message: actualMessage,
      sender: sender?.toString()
    });
  }
}

/**
 * 死信监视器 Actor，监听系统中的死信事件并进行处理
 */
export class DeadLetterWatcher {
  /**
   * 创建死信监视器
   * @param system Actor 系统
   * @returns 死信监视器 PID
   */
  static spawn(system: ActorSystem): PID {
    // 创建死信进程
    const process = new DeadLetterProcess(system);
    
    // 注册死信进程
    const id = "deadLetter";
    const pid = system.processRegistry.add(process, id);
    
    // 订阅死信事件
    system.eventStream.subscribe(Events.DeadLetter, (event: Events.DeadLetter) => {
      // 这里可以添加额外的死信处理逻辑，如计数、记录等
      console.debug(`[DeadLetterWatcher] Received dead letter: ${event.pid.toString()}`, {
        message: event.message,
        sender: event.sender?.toString()
      });
    });
    
    return pid;
  }
} 